package org.tool.collection;

import cn.hutool.core.util.ObjectUtil;

import java.util.*;

/**
 * 集合相关工具类
 *
 * @author LiKun
 * @date 2021/11/6 15:03
 */
public abstract class CollectionUtil {

    /**
     * MySQL 数据库批量插入支持的最大记录数
     */
    public static final int MYSQL_MAX_INSERT_SIZE = 1000;

    /**
     * 合并给定的集合数据
     *
     * @param collections 待合并的集合数据
     *
     * @return 合并后的集合数据
     */
    public static Collection mergeCollection(Collection... collections) {
        if (ObjectUtil.isNotEmpty(collections)) {
            Collection baseCollection = null;

            for (Collection collection : collections) {
                if (ObjectUtil.isNotEmpty(collection)) {
                    if (Objects.nonNull(baseCollection)) {
                        baseCollection.addAll(collection);
                    } else {
                        baseCollection = collection;
                    }
                }
            }
            return Objects.nonNull(baseCollection) ? baseCollection : Collections.emptyList();
        }
        return Collections.emptyList();
    }

    /**
     * 将给定的集合切分为可以被一次装入到 ORACLE 数据库 IN 语句的小集合中
     *
     * @param collection 原始数据集合
     * @param <T>        泛型
     *
     * @return 切分后的数据集合
     */
    public static <T> List<List<T>> segmentCollection(Collection<T> collection) {
        return segmentCollection(collection, MYSQL_MAX_INSERT_SIZE);
    }

    /**
     * 将给定的集合切分为可以被一次装入到 ORACLE 数据库 IN 语句的小集合中
     *
     * @param collection 原始数据集合
     * @param <T>        泛型
     *
     * @return 切分后的数据集合
     */
    public static <T> List<List<T>> segmentCollection(Collection<T> collection, int preSize) {
        if (ObjectUtil.isNotEmpty(collection) && preSize > 0) {
            int size = collection.size() / preSize;
            boolean sizeIsRedundant = collection.size() % preSize != 0;
            List<List<T>> segmentContainer = new ArrayList<>(sizeIsRedundant ? size : size + 1);
            List<T> allBusinessData = (collection instanceof List) ? (List<T>) collection : new ArrayList<>(collection);

            for (int index = 0; index <= size; index++) {
                if (size == index) {
                    if (sizeIsRedundant) {
                        segmentContainer.add(allBusinessData.subList(index * preSize, collection.size()));
                    }
                } else {
                    segmentContainer.add(allBusinessData.subList(index * preSize, (index + 1) * preSize));
                }
            }
            return segmentContainer;
        }
        return Collections.emptyList();
    }

}
